
#include <stdio.h>
#include <sys/types.h>
#include <string.h>

#include "bocat/common/md5.hpp"


namespace	bocat	{
namespace	common	{

MD5::MD5()
{
	updating = false;
}


void
MD5::clear()
{
	memset( md5, 0, sizeof(md5) );
	memset( md5_hex, 0, sizeof(md5_hex) );

	MD5_Init( &ctx );

	updating = false;
}


void
MD5::update( const void* data, u_int32_t data_size )
{
	if (!updating) {
		clear();
		updating = true;
	}

	MD5_Update( &ctx, data, data_size );
}

const char*
MD5::digest()
{
	if (updating) {
		MD5_Final( md5, &ctx );

		updating = false;
	}

	void*	p = static_cast< void * >(md5);

	return static_cast< char * >( p );
}


const char*
MD5::hexdigest()
{
	static const char hex[16] =
			{
			  '0', '1', '2', '3', '4', '5', '6', '7',
			  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
			};

	if (updating) {
		MD5_Final( md5, &ctx );

		updating = false;
	}

	if (0 == md5_hex[0]) {
		char*	p = md5_hex;
		for (int i=0; i<16; i++) {
			unsigned val = md5[i];

			*(p++) = hex[ val >> 4 ];
			*(p++) = hex[ val & 0x0f ];
		}
	}

	return md5_hex;
}

}	////	namespace	common
}	////	namespace	bocat

